package com.wujilin.okra.model;

import android.content.ContentValues;
import android.database.Cursor;

/**
 * The model class for a shorter name against to the ContentValues class.
 *
 * @author Belin Wu
 * 
 */
public class Model {
    private ContentValues values;

    public Model() {
    	values = new ContentValues();
    }
    
    public Model(int size) {
    	values = new ContentValues(size);
    }
    
    public Model(ContentValues values) {
    	this.values = values;
    }

    @SuppressWarnings("unchecked")
	public <T> T get(String key) {
        return (T) values.get(key);
    }
    
    public Long getId() {
    	return values.getAsLong("_id");
    }
    
    public Long getLong(String key) {
    	return values.getAsLong(key);
    }
    
    public Integer getInteger(String key) {
    	return getInteger(key, 0);
    }
    
    public Integer getInteger(String key, Integer defaultValue) {
    	Integer value = values.getAsInteger(key);
    	return value == null ? defaultValue : value;
    }
    
    public Boolean getBoolean(String key) {
    	return values.getAsBoolean(key);
    }
    
    public String getString(String key) {
    	String value = values.getAsString(key);
    	return value == null ? "" : value;
    }
    
    public Double getDouble(String key) {
    	return values.getAsDouble(key);
    }
    
    public Float getFloat(String key) {
    	return values.getAsFloat(key);
    }

    public Model set(String key, Boolean value) {
    	values.put(key, value);
        return this;
    }
    
    public Model set(String key, Integer value) {
    	values.put(key, value);
        return this;
    }
    
    public Model set(String key, String value) {
    	values.put(key, value);
        return this;
    }
    
    public Model set(String key, Double value) {
    	values.put(key, value);
        return this;
    }
    
    public Model set(String key, Float value) {
    	values.put(key, value);
    	return this;
    }
    
    public Model set(String key, Long value) {
    	values.put(key, value);
        return this;
    }
    
    public Model set(String key, byte[] value) {
    	values.put(key, value);
    	return this;
    }
    
    public Model set(String key) {
    	values.putNull(key);
    	return this;
    }
    
    public int size() {
        return values.size();
    }
    
    public ContentValues values() {
    	return values;
    }
    
    public static Model of(Object... values) {
    	int length = values.length;
    	if (length == 0 || length % 2 != 0) {
    		throw new IllegalArgumentException("");
    	}
    	Model model = new Model(length / 2);
    	for (int i = 0; i < length; i++) {
    		String key = values[i].toString();
    		Object value = values[++i];
    		if (value != null) {
    			Class<?> type = value.getClass();
    			if (type == String.class) {
    				model.set(key, value.toString());
    			} else if (type == Integer.class || type == int.class) {
    				model.set(key, (Integer) value);
    			} else if (type == Long.class || type == long.class) {
    				model.set(key, (Long) value);
    			} else if (type == Double.class || type == double.class) {
    				model.set(key, (Double) value);
    			} else if (type == Float.class || type == float.class) {
    				model.set(key, (Float) value);
    			} else if (type == Boolean.class || type == boolean.class) {
    				model.set(key, (Boolean) value);
    			} else if (type == byte[].class) {
    				model.set(key, (byte[]) value);
    			}
    			continue;
    		}
    		model.set(key);
    	}
    	return model;
    }
    
    public static Model of(Cursor cursor) {
    	int columnCount = cursor.getColumnCount();
		Model model = new Model(columnCount);
		for (int i = 0; i < columnCount; i++) {
			int columnType = cursor.getType(i);
			String columnName = cursor.getColumnName(i);
			switch (columnType) {
			case Cursor.FIELD_TYPE_BLOB:
				model.set(columnName, cursor.getBlob(i));
				break;
			case Cursor.FIELD_TYPE_STRING:
				model.set(columnName, cursor.getString(i));
				break;
			case Cursor.FIELD_TYPE_FLOAT:
				model.set(columnName, cursor.getFloat(i));
				break;
			case Cursor.FIELD_TYPE_INTEGER:
				model.set(columnName, cursor.getInt(i));
				break;
			case Cursor.FIELD_TYPE_NULL:
				model.set(columnName);
				break;
			}
		}
    	return model;
    }
}
